﻿#include <QWidget>
#include <QPixmap>
#include <QImage>
#include <windows.h>
#include "dib.h"
#include "qtwain.h"
Q_GUI_EXPORT QPixmap qt_pixmapFromWinHBITMAP(HBITMAP bitmap, int hbitmapFormat = 0);
#pragma execution_character_set("utf-8")；

QTwain::QTwain(QWidget* parent, HWND id)
    : CTwain(id)
{
    m_bEmitPixmaps = false;
}

QTwain::~QTwain()
{	
    setParent(nullptr);
	ReleaseTwain();
}

//使用twain默认的ui选择数据源
bool QTwain::selectSource()
{
	return (SelectSource() == true);
}

bool QTwain::acquire(unsigned int maxNumImages)
{
    qDebug()<<"type "<<type<<" papersize "<<papersize<<" img_model "<<img_model<<" fenbianlv "<<fenbianlv;

    //参数1是扫描的最大张数，比如设为2则扫描2张纸之后就停止扫描了
    return (Acquire(TWCPP_ANYCOUNT,type,papersize,img_model,fenbianlv) == true);
}

bool QTwain::isValidDriver() const
{
	return (IsValidDriver() == true);
}

void QTwain::CopyImage(HANDLE hBitmap, TW_IMAGEINFO& info)
{
//    CDIB * dib = new CDIB();
//	CDIB temp_dib;
//	temp_dib.CreateFromHandle(hBitmap, info.BitsPerPixel);
//	if (info.BitsPerPixel == 24)
//    {
//        *dib = temp_dib;
//    }
//	else
//    {
//        Create24Bit(temp_dib, *dib);
//    }

//	if (emitPixmaps())
//	{
//		QPixmap* retval = convertToPixmap(dib);
//		emit pixmapAcquired(retval);
//        qDebug()<<"发射图片";
//		delete dib;
//	}

    SetImage(hBitmap,info.BitsPerPixel);
}

void QTwain::SetImage(HANDLE hBitmap,int bits)
{
    CDIB dib;
    dib.CreateFromHandle(hBitmap,bits);
    SYSTEMTIME sys;
    long t1 = GetTickCount();

    QPixmap * Pixmap = convertToPixmap(&dib);
    bool b = Pixmap->save(tr("name%1.png").arg(t1));
    qDebug()<<"保存图片结果："<<b;

    delete Pixmap;
}

static unsigned char masktable[] = { 0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01 };

void QTwain::Create24Bit(CDIB& source,CDIB& dest)
{
	int pal;
	dest.Create(source.Width(),source.Height(),24);
	pal = source.GetPaletteSize();
	BYTE palet[768];

	for(int i=0; i < pal; i++)
	{
		COLORREF col = source.PaletteColor(i);
		palet[i*3+2] = GetRValue(col);
		palet[i*3+1] = GetGValue(col);
		palet[i*3+0] = GetBValue(col);
	}

	int j;
	int i;
	BYTE *src,*dst,*ptr;

	for(i=0; i < source.Height(); i++)
	{
		src = source.GetLinePtr(i);
		dst = dest.GetLinePtr(i);
		ptr = dst;
        int index = 0;
		for(j=0; j < source.Width(); j++,ptr+=3)
		{
			switch(pal)
			{
                case 2:
                    if(src[j>>3] & masktable[j&7])
                    {
                        index = 1;
                    }
                    else
                    {
                        index = 0;
                    }
                    break;
                case 16:
                    if(j & 1)
                    {
                        index = src[j>>1] & 0x0f;
                    }
                    else
                    {
                        index = (src[j>>1] >> 4) & 0x0f;
                    }
                    break;
                case 256:
                    index = src[j];
                    break;
			}
			Q_ASSERT(index < pal);
			memcpy(ptr,palet+index*3,3);
		}
		index = (ptr - dst)/3;
		Q_ASSERT(index <= source.Width());
    }
}

bool QTwain::onSetParent()
{
    HWND id = HWND(m_pParent->winId());
    qDebug()<<"非构造函数中安装Twain";
	InitTwain(id);
    emit already_get_sour_list();

	return IsValidDriver();
}

void QTwain::setParent(QWidget* parent)
{
    m_pParent = parent;
    if (parent)
    {
        if (!onSetParent())
        {
            qDebug()<<"安装Twain失败";
        }
    }
}

//位图转为QPixmap
QPixmap* QTwain::convertToPixmap(CDIB* pDib)
{
    if (!pDib)
    {
        return nullptr;
    }

    unsigned int nUseWidth = pDib->Width();
    unsigned int nUseHeight = pDib->Height();

    HANDLE hdib = pDib->DIBHandle();//位图的头部
    HPALETTE pepe = CreateDIBPalette(hdib);
    HBITMAP ima = DIBToBitmap(hdib,pepe);

    QPixmap* retval2 = new QPixmap(qt_pixmapFromWinHBITMAP(ima));

    return retval2;
}

//位图转为QImage 有问题的函数
QImage* QTwain::convertToImage(CDIB* pDib, unsigned int nWidth, unsigned int nHeight)
{
    if (!pDib)
    {
        return nullptr;
    }

    unsigned int nUseWidth  = nWidth;
    unsigned int nUseHeight = nHeight;

    if (nUseWidth == 0)
    {
        nUseWidth = pDib->Width();
    }

    if (nUseHeight == 0)
    {
        nUseHeight = pDib->Height();
    }

    QPixmap pixmap(pDib->Width(), pDib->Height());

    QImage* retval = new QImage( pixmap.toImage().scaled(nUseWidth, nUseHeight,Qt::KeepAspectRatio,Qt::SmoothTransformation) );
    return retval;
}

//有问题的函数
CDIB* QTwain::convertToDib(QPixmap* pPixmap, unsigned int nWidth, unsigned int nHeight)
{
    CDIB* pRetval = new CDIB();

    /**
     * @todo implement this function
     */

    return pRetval;
}
